Entry And Exit Code

A single spinlock protects the entire kernel. The interrupt handlers, the syscall entry code and the exception handlers all acquire the lock before entering the kernel proper. When the processor is trying to acquire the spinlock it spins continually on the lock with interrupts disabled. This causes a specific deadlock problem. The lock owner may need to send an invalidate request to the rest of the processors and wait for these to complete before continuing. A processor spinning on the lock would not be able to do thus. Thus the loop of the spinlock tests and handles invalidate requests. If the invalidate bit for the spinning CPU is set the processor invalidates its TLB and atomically clears the bit. When the spinlock is obtained that processor will take an IPI and in the IPI test the bit and skip the invalidate as the bit is clear.

One complexity of the spinlock is that a process running in kernel mode can sleep voluntarily and be pre-empted. A switch from such a process to a process executing in user space may reduce the lock count. To track this the kernel uses a syscall_count and a per process lock_depth parameter to track the kernel lock state. The switch_to() function is modified in SMP mode to adjust the lock appropriately.

The final problem is the idle thread. In the single processor kernel the idle thread executes 'hlt' instructions. This saves power and reduces the running temperature of the processors when they are idle. However it means the process spends all its time in kernel mode and would thus hold the kernel spinlock. The SMP idle thread continually reschedules a new task and returns to user mode. This is far from ideal and will be modified to use 'hlt' instructions and release the spinlock soon. Using 'hlt' is even more beneficial on a multiprocessor system as it almost completely takes an idle processor off the bus.

Interrupts are distributed by an i82489 APIC. This chip is set up to work as an emulation of the traditional PC interrupt controllers when the machine boots (so that an Intel MP machine boots one CPU and PC compatible). The kernel has all the relevant locks but does not yet reprogram the 82489 to deliver interrupts to arbitrary processors as it should. This requires further modification of the standard Linux interrupt handling code, and is particularly messy as the interrupt handler behaviour has to change as soon as the 82489 is switched into SMP mode.